home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / POV-Ray 3.0.2 / src / MacSource / FilePrefs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-03  |  47.7 KB  |  1,412 lines  |  [TEXT/CWIE]

  1. /*==============================================================================
  2. Project:    POV-Ray
  3.  
  4. Version:    3
  5.  
  6. File:    FilePrefs.c
  7.  
  8. Description: File/rendering preferences dialog handling code
  9. ------------------------------------------------------------------------------
  10. Author:
  11.     Eduard [esp] Schwan
  12. ------------------------------------------------------------------------------
  13.     from Persistence of Vision(tm) Ray Tracer
  14.     Copyright 1996 Persistence of Vision Team
  15. ------------------------------------------------------------------------------
  16.     NOTICE: This source code file is provided so that users may experiment
  17.     with enhancements to POV-Ray and to port the software to platforms other 
  18.     than those supported by the POV-Ray Team.  There are strict rules under
  19.     which you are permitted to use this file.  The rules are in the file
  20.     named POVLEGAL.DOC which should be distributed with this file. If 
  21.     POVLEGAL.DOC is not available or for more info please contact the POV-Ray
  22.     Team Coordinator by leaving a message in CompuServe's Graphics Developer's
  23.     Forum.  The latest version of POV-Ray may be found there as well.
  24.  
  25.     This program is based on the popular DKB raytracer version 2.12.
  26.     DKBTrace was originally written by David K. Buck.
  27.     DKBTrace Ver 2.0-2.12 were written by David K. Buck & Aaron A. Collins.
  28. ------------------------------------------------------------------------------
  29. Change History:
  30.     941230    [esp]    Created
  31.     950514    [esp]    Fixed outfile popup not being inited.
  32.     951014    [esp]    Added a bunch of 3.0b2 fields.
  33.     960405    [esp]    Added Restore Default button from user request (3.0b6c)
  34.     960518    [esp]    Fixed bug where Animation not always updated properly
  35. ==============================================================================*/
  36.  
  37. #define FILEPREFS_C
  38.  
  39. #include "FilePrefs.h"
  40.  
  41. /*==== Macintosh-specific headers ====*/
  42. #include <errors.h>            /* dupFNErr, etc */
  43. #include <Resources.h>
  44. #include <Controls.h>
  45.  
  46. #include "AppPrefs.h"
  47. #include "ScreenUtils.h"    // ForceRectOnScreen
  48. #include "DialogUtils.h"    // FlashDItem
  49. #include "Animate.h"
  50.  
  51. // ---------------------------------------------------------------------
  52. //
  53. // Rendering Options Dialog items
  54. //
  55. #define    kNoItemHit                -1
  56. // Base DITL items, these never change
  57. #define    kDLOG_RenderPrefsMain 3000                // base dialog/DITL ID
  58. #define    kPU_Settings            4
  59. #define    kCB_SaveAsDefault        5
  60. #define    kPB_RestoreDefault        6
  61. #define    kST_Filename            7
  62. #define    kPC_SubBorder            15                // used to position sub-ditl relative
  63. #define    kMainItem_Max            kPC_SubBorder    // used to figure ShortenDITL
  64.  
  65. #define KDITL_RPInput        kDLOG_RenderPrefsMain+1
  66. #define kPU_LangVersion            kMainItem_Max+1
  67.  
  68. #define KDITL_RPQuality        KDITL_RPInput+1
  69. #define    kPU_RenderQuality        kMainItem_Max+1
  70. #define    kPU_PreviewStart        kMainItem_Max+2
  71. #define    kPU_PreviewEnd            kMainItem_Max+3
  72. #define    kCB_DoAntiAlias            kMainItem_Max+4
  73. #define    kET_AntiAliasThresh        kMainItem_Max+5
  74. #define    kET_AntialiasDepth        kMainItem_Max+6
  75. #define    kET_AntiJitterScale        kMainItem_Max+7
  76. #define    kPU_AntialiasMethod        kMainItem_Max+8
  77. #define    kST_AntiAliasThresh        kMainItem_Max+9
  78. #define    kST_AntialiasDepth        kMainItem_Max+10
  79. #define    kST_AntiJitterScale        kMainItem_Max+11
  80. #define    kCB_RadQuality            kMainItem_Max+12
  81.  
  82. #define KDITL_RPOptimiz        KDITL_RPQuality+1
  83. #define    kPU_MaxBounds            kMainItem_Max+1
  84. #define    kCB_UseLBuffer            kMainItem_Max+2
  85. #define    kCB_UseVBuffer            kMainItem_Max+3
  86. #define    kCB_UseVDraw            kMainItem_Max+4
  87. #define    kCB_SplitUnions            kMainItem_Max+5
  88. #define    kCB_RemoveUnused        kMainItem_Max+6
  89.  
  90. #define KDITL_RPInfo        KDITL_RPOptimiz+1
  91. #define kPU_Progress            kMainItem_Max+1
  92. #define kCB_DoCreateIni            kMainItem_Max+2
  93.  
  94. #define KDITL_RPOutputSize    KDITL_RPInfo+1
  95. #define    kPU_ImageSize            kMainItem_Max+1
  96. #define    kET_ImageWidth            kMainItem_Max+2
  97. #define    kET_ImageHeight            kMainItem_Max+3
  98. #define    kET_ColFrom                kMainItem_Max+4
  99. #define    kET_ColTo                kMainItem_Max+5
  100. #define    kET_RowFrom                kMainItem_Max+6
  101. #define    kET_RowTo                kMainItem_Max+7
  102.  
  103. #define KDITL_RPOutputFile    KDITL_RPOutputSize+1
  104. #define    kET_PICTSig                kMainItem_Max+1
  105. #define    kPU_OutfileType            kMainItem_Max+2
  106. #define    kCB_ContinueFromTarga    kMainItem_Max+3
  107. #define    kET_TargaSig            kMainItem_Max+4
  108. #define    kPU_OutfileBuffSize        kMainItem_Max+5
  109. #define    kCB_DoHistFile            kMainItem_Max+6
  110. #define    kPU_HistFileType        kMainItem_Max+7
  111. #define    kPU_BitsPerColor        kMainItem_Max+8
  112. #define    kCB_DoAlphaChannel        kMainItem_Max+9
  113.  
  114. #define KDITL_RPAnimate        KDITL_RPOutputFile+1
  115. #define    kCB_Animate                kMainItem_Max+1
  116. #define    kST_FrameVal0            kMainItem_Max+2
  117. #define    kET_FrameValS            kMainItem_Max+3
  118. #define    kET_FrameValE            kMainItem_Max+4
  119. #define    kET_FrameValN            kMainItem_Max+5
  120. #define    kET_ClockVal0            kMainItem_Max+6
  121. #define    kST_ClockValS            kMainItem_Max+7
  122. #define    kST_ClockValE            kMainItem_Max+8
  123. #define    kET_ClockValN            kMainItem_Max+9
  124. #define    kPU_FieldRender            kMainItem_Max+10
  125.  
  126. // orphans for now...
  127. #define    kCB_DoPICTCmp            kMainItem_Max+1
  128. #define    kBT_PICTCmpSettings        kMainItem_Max+1
  129.  
  130.  
  131.  
  132. /*==== globals ====*/
  133. file_prefs_hdl_t    gFilePrefs_h = NULL;    // each file has its own prefs
  134. file_prefs_hdl_t    gPrefs2Use_h = NULL;    // points to file or default prefs
  135.  
  136. /*==== locals ====*/
  137. static    short        gSrcResRefNum = kRsrcFileClosed;
  138. static    short        gCurrDITLID = KDITL_RPOutputSize;    // which pane are we in
  139. static    short        gPrevItemHit;            // tracks previous item hit in dialog
  140.  
  141. static    short        gSrc_wdrefnum;
  142. static    StringPtr    gSrc_fname;
  143. static    file_prefs_rec_t    gOrigPrefs;        // remember old prefs in case of cancel
  144.  
  145.  
  146. // ---------------------------------------------------------------------
  147. // Should move this to DialogUtils...
  148. static void ShowHideDItem(DialogRef theDialog, short itemNo, Boolean showIt)
  149. {
  150.     if (showIt)
  151.         ShowDialogItem(theDialog, itemNo);
  152.     else
  153.         HideDialogItem(theDialog, itemNo);
  154. }
  155.  
  156. // ---------------------------------------------------------------------
  157. // Determine height and width from item# of Image menu passed
  158. static void GetImageSizeOfItem(MenuRef imageMenuRef, short pItemNumber, short *  pWidth, short * pHeight)
  159. {
  160.     char    itemText[63];
  161.     char    *itemTextPtr;
  162.  
  163.     // set the width/height invalid until properly read
  164.     *pWidth = -1;
  165.     *pHeight = -1;
  166.  
  167.     // get the text of the menu item as a C string
  168.     GetMenuItemText(imageMenuRef, pItemNumber, (StringPtr)itemText);
  169.     p2cstr((StringPtr)itemText);
  170.     // convert the first ASCII number to a number
  171.     *pWidth = atoi(itemText);
  172.     // find the position of the second number (right after the "x")
  173.     itemTextPtr = strchr(itemText, 'x');
  174.     if (itemTextPtr != NULL)
  175.         {
  176.         // convert second ASCII number to a number
  177.         itemTextPtr++; // skip the space after the 'x'
  178.         *pHeight = atoi(itemTextPtr);
  179.         }
  180. }
  181.  
  182.  
  183. // ---------------------------------------------------------------------
  184. // Determine closest index in the image menu to the h/v passed
  185. static short GetClosestImageSizeItem(WindowPtr dlgWindPtr, short pWidth, short pHeight)
  186. {
  187.     short        numItems=0;
  188.     ControlHandle    popupControlH;
  189.     MenuRef        imageMenuRef;
  190.     int            k;
  191.  
  192.     // get the popup menu control, then get menu handle from it
  193.     popupControlH = (ControlHandle)GrabDItemHandle(dlgWindPtr, kPU_ImageSize);
  194.         // popup menu handle inside struct pointed to by contrlData handle! (NIM:Essentials:5-28,5-77)
  195.     if (popupControlH)
  196.         imageMenuRef = (MenuRef) (**(Handle**)(**popupControlH).contrlData);
  197.  
  198.     // go down the list & find a match
  199.     if (imageMenuRef)
  200.         numItems = CountMenuItems(imageMenuRef);
  201.     for (k=1; k<=numItems; k++)
  202.         {
  203.         short    itemWidth, itemHeight;
  204.         // what's the size of this item?
  205.         GetImageSizeOfItem(imageMenuRef, k, &itemWidth, &itemHeight);
  206.         // if this item is just bigger than the user's item, return this index
  207.         if ((itemWidth >= pWidth) && (itemHeight >= pHeight))
  208.             return k;    // return item #
  209.         }
  210.  
  211.     // no match, return max
  212.     return numItems;
  213. }
  214.  
  215.  
  216. // ---------------------------------------------------------------------
  217. // Open a source file's resource fork for getting/putting settings info
  218. static void FilePrefs_Open(short src_wdrefnum, StringPtr src_fname)
  219. {
  220.     if (src_wdrefnum != 0)    // if there is a file open..
  221.     {
  222.         SetVol(NULL, src_wdrefnum);
  223.         if (gSrcResRefNum != kRsrcFileClosed)
  224.             printf("## ERROR! opening already-opened rsrc file: OpenFilePrefs()\n");
  225.         gSrcResRefNum = OpenResFile(src_fname);
  226.         if (gSrcResRefNum == kRsrcFileClosed)
  227.         {
  228.             CreateResFile(src_fname);
  229.             gSrcResRefNum = OpenResFile(src_fname);
  230.         }
  231.     }
  232. } // FilePrefs_Open
  233.  
  234.  
  235.  
  236. // ---------------------------------------------------------------------
  237. // Close the source file's resource fork
  238. static void FilePrefs_Close(void)
  239. {
  240.     if (gSrcResRefNum != kRsrcFileClosed)
  241.         CloseResFile(gSrcResRefNum);
  242.     gSrcResRefNum = kRsrcFileClosed;
  243. } // FilePrefs_Close
  244.  
  245.  
  246.  
  247. // ---------------------------------------------------------------------
  248. // Update the source file's settings info
  249. void FilePrefs_Write(short src_wdrefnum, StringPtr src_fname)
  250. {
  251.     short                oldRefNum;
  252.     file_prefs_hdl_t    tmpFilePrefsHandle;
  253.  
  254.     oldRefNum = CurResFile();
  255.     if (gSrcResRefNum == kRsrcFileClosed)
  256.         FilePrefs_Open(src_wdrefnum, src_fname);
  257.  
  258.     if (gSrcResRefNum != kRsrcFileClosed)
  259.     {
  260.         /* switch over to our open file */
  261.         UseResFile(gSrcResRefNum);
  262.  
  263.         /* as long as there are old file prefs resources, delete them */
  264.         do {
  265.             tmpFilePrefsHandle = (file_prefs_hdl_t)Get1IndResource(kFilePrefsRsrc, 1);
  266.             if (tmpFilePrefsHandle != NULL)
  267.             {
  268.                 RemoveResource((Handle)tmpFilePrefsHandle);
  269.                 UpdateResFile(gSrcResRefNum);
  270.                 DisposeHandle((Handle)tmpFilePrefsHandle);
  271.             }
  272.         } while (tmpFilePrefsHandle != NULL);
  273.  
  274.         /* Create a new resource to add */
  275.         tmpFilePrefsHandle = (file_prefs_hdl_t)NewHandle(sizeof(file_prefs_rec_t));
  276.  
  277.         /* Fill it up and add it to file */
  278.         if (tmpFilePrefsHandle != NULL)
  279.         {
  280.             **tmpFilePrefsHandle = **gFilePrefs_h;
  281.             AddResource((Handle)tmpFilePrefsHandle, kFilePrefsRsrc, kFilePrefs_rsrcID, "\pPOV-Ray File Prefs");
  282.             WriteResource((Handle)tmpFilePrefsHandle);
  283.             ReleaseResource((Handle)tmpFilePrefsHandle);
  284.         }
  285.         FilePrefs_Close();
  286.         UseResFile(oldRefNum);
  287.     } // if opened
  288. } // FilePrefs_Write
  289.  
  290.  
  291.  
  292. // ---------------------------------------------------------------------
  293. // Read the setting info from the source file
  294. void FilePrefs_Read(short src_wdrefnum, StringPtr src_fname)
  295. {
  296.     short                oldRefNum;
  297.     file_prefs_hdl_t    tmpFilePrefsHandle = NULL;
  298.  
  299.     oldRefNum = CurResFile();
  300.     if (gSrcResRefNum == kRsrcFileClosed)
  301.         FilePrefs_Open(src_wdrefnum, src_fname);
  302.  
  303.     if (gSrcResRefNum != kRsrcFileClosed)
  304.         tmpFilePrefsHandle = (file_prefs_hdl_t)Get1Resource(kFilePrefsRsrc, kFilePrefs_rsrcID);
  305.  
  306.     if (tmpFilePrefsHandle != NULL)
  307.     {
  308.         /* Is it the wrong version? */
  309.         if ((**tmpFilePrefsHandle).prefsVersion != kFilePrefs_Vers)
  310.         {    /* old version, delete & create new one below! */
  311.             RemoveResource((Handle)tmpFilePrefsHandle);
  312.             UpdateResFile(gSrcResRefNum);
  313.             DisposeHandle((Handle)tmpFilePrefsHandle);
  314.             tmpFilePrefsHandle = NULL; /* flag code below to add new */
  315.         }
  316.         /* Still got it?  Use it! */
  317.         if (tmpFilePrefsHandle != NULL)
  318.         {
  319.             **gFilePrefs_h = **tmpFilePrefsHandle;
  320.             /* make sure our windows are on THIS MACHINE'S screens */
  321.             ForceRectOnScreen(&(**gFilePrefs_h).srcWind_pos);
  322.             ForceRectOnScreen(&(**gFilePrefs_h).statWind_pos);
  323.             ForceRectOnScreen(&(**gFilePrefs_h).imageWind_pos);
  324.  
  325.             if ((**gDefltFilePrefs_h).progress >= eProgDebug)
  326.             {
  327.                 printf("-d GetFilePrefs():\n");
  328.                 printf("-d   ImageWind = <%d, %d, %d, %d>\n",
  329.                     (**gFilePrefs_h).imageWind_pos.left,
  330.                     (**gFilePrefs_h).imageWind_pos.top,
  331.                     (**gFilePrefs_h).imageWind_pos.right,
  332.                     (**gFilePrefs_h).imageWind_pos.bottom);
  333.                 printf("-d   srcWind = <%d, %d, %d, %d>\n",
  334.                     (**gFilePrefs_h).srcWind_pos.left,
  335.                     (**gFilePrefs_h).srcWind_pos.top,
  336.                     (**gFilePrefs_h).srcWind_pos.right,
  337.                     (**gFilePrefs_h).srcWind_pos.bottom);
  338.             }
  339.  
  340.         }
  341.     }
  342.  
  343.     /* create a new one if can't read or use the old one */
  344.     if (tmpFilePrefsHandle == NULL)
  345.     {
  346.         **gFilePrefs_h = **gDefltFilePrefs_h;    // get default settings
  347.         FilePrefs_Write(src_wdrefnum, src_fname);
  348.     }
  349.     else
  350.         {
  351.         ReleaseResource((Handle)tmpFilePrefsHandle);
  352.         FilePrefs_Close();
  353.         }
  354.     UseResFile(oldRefNum);
  355. } // FilePrefs_Read
  356.  
  357.  
  358. // ---------------------------------------------------------------------
  359. // Pin the value x between a and b, i.e.  a <= x <= b
  360. static long PinValue(long x, long a, long b)
  361. {
  362.     long    r = x;
  363.     if (r < a)
  364.         r = a;
  365.     else
  366.         if (r > b)
  367.             r = b;
  368.     return r;
  369. } // PinValue
  370.  
  371.  
  372.  
  373. // ---------------------------------------------------------------------
  374. // clear a rectangular area of a window
  375. static void erase_TE_rect(WindowPtr dlgWindPtr, Rect *pRect)
  376. {
  377. #pragma unused (dlgWindPtr)
  378.     PenState    thePen;
  379.     Rect        outerRect;
  380.  
  381.     // Save and restore the pen state so we don't mess things up
  382.     // for other drawing routines
  383.     GetPenState(&thePen);
  384.  
  385.     outerRect = *pRect;
  386.     InsetRect(&outerRect, -3, -3); // border outside TE item
  387.     ForeColor(whiteColor);
  388.     FrameRect(&outerRect);
  389.  
  390.     SetPenState(&thePen);
  391.     ForeColor(blackColor);
  392. }
  393.  
  394.  
  395. // ---------------------------------------------------------------------
  396. // dim a rectangular area of a window
  397. static void dim_rect(WindowPtr dlgWindPtr, Rect *pRect)
  398. {
  399. #pragma unused (dlgWindPtr)
  400.     PenState    thePen;
  401.  
  402.     // Save and restore the pen state so we don't mess things up
  403.     // for other drawing routines
  404.     GetPenState(&thePen);
  405.     PenMode(notPatBic);
  406.  
  407.     PenPat((ConstPatternParam)&qd.gray);
  408.     PaintRect(pRect);
  409.  
  410.     SetPenState(&thePen);
  411. }
  412.  
  413.  
  414. // ---------------------------------------------------------------------
  415. // dim/enable the aa edit text fields
  416. static void update_edit_text(WindowPtr dlgWindPtr, short theTEItemID, Boolean isActive)
  417. {
  418.     short int        itemType;
  419.     GrafPtr            saveGP;
  420.     Rect            aRect;
  421.     Handle            theTEControlH;
  422.  
  423.     GetPort(&saveGP);
  424.     SetPort(dlgWindPtr);
  425.  
  426.     // Get the actual TE item
  427.     GetDialogItem(dlgWindPtr, theTEItemID, &itemType, &theTEControlH, &aRect);
  428.  
  429.     // dim/enable the TE item
  430.     if (isActive)
  431.         {    // set to enabled EditText item
  432.         GetDialogItem(dlgWindPtr, theTEItemID, &itemType, &theTEControlH, &aRect);
  433.          SetDialogItem(dlgWindPtr, theTEItemID, editText, theTEControlH, &aRect);
  434.         // invalidate TEs so they are redrawn
  435.         InsetRect(&aRect, -5, -5); // just outside TE item
  436.         InvalRect(&aRect);
  437.         }
  438.     else
  439.         {    // aa is OFF, disable & dim TE item
  440.         // make it think it is a static text item, not EditText
  441.         GetDialogItem(dlgWindPtr, theTEItemID, &itemType, &theTEControlH, &aRect);
  442.          erase_TE_rect(dlgWindPtr, &aRect);
  443.         SetDialogItem(dlgWindPtr, theTEItemID, statText+itemDisable, theTEControlH, &aRect);
  444.  
  445.         InsetRect(&aRect, -5, -5); // just outside TE item
  446.         InvalRect(&aRect);
  447.         } // else off
  448.  
  449.     SetPort(saveGP);
  450. } // update_edit_text
  451.  
  452.  
  453. // ---------------------------------------------------------------------
  454. static void SlideInNewDITL(DialogPtr myDialog)
  455.     {
  456.     short        numDITLs2Remove;
  457.     gCurrDITLID = kDLOG_RenderPrefsMain + GetDialogItemValue(myDialog, kPU_Settings);
  458.     // First Remove previous DITL items, if any...
  459.     numDITLs2Remove = CountDITL(myDialog) - kMainItem_Max;
  460.     if (numDITLs2Remove>0)
  461.         ShortenDITL(myDialog, numDITLs2Remove);
  462.     // Now add new ones on
  463.     OverlayDITLOnDialog(myDialog, gCurrDITLID, kPU_Settings);
  464.     } // SlideInNewDITL
  465.  
  466.  
  467. // ---------------------------------------------------------------------
  468. static void SetupDitls_RPInput(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  469.     {
  470.     // Set the Language Version popup
  471.     if (thePrefs->languageVersion < eMinLangVersion)
  472.         thePrefs->languageVersion = eMinLangVersion;
  473.     else if (thePrefs->languageVersion > eMaxLangVersion)
  474.         thePrefs->languageVersion = eMaxLangVersion;
  475.     SetDialogItemValue(myDialog, kPU_LangVersion, thePrefs->languageVersion);
  476.  
  477.     } // SetupDitls_RPInput
  478.  
  479.  
  480. static void ItemHit_RPInput(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  481.     {
  482. #pragma unused(itemHit)
  483.     thePrefs->languageVersion = GetDialogItemValue(myDialog, kPU_LangVersion);
  484.     }
  485.  
  486.  
  487. // ---------------------------------------------------------------------
  488. static void SetupDitls_RPQuality(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  489.     {
  490.     char        buff[128];
  491.  
  492.     // Set the Image Quality popup
  493.     if (thePrefs->renderQuality > 9)
  494.         thePrefs->renderQuality = 9;
  495.     SetDialogItemValue(myDialog, kPU_RenderQuality, thePrefs->renderQuality+1);
  496.  
  497.     // Set the Radiosity Quality popup
  498.     // If render quality is less than 8, then Radiosity MUST BE OFF
  499.     if (thePrefs->renderQuality < 8)
  500.         {
  501.         thePrefs->radQuality = 0;
  502.         }
  503.  
  504.     SetDialogItemValue(myDialog, kCB_RadQuality, thePrefs->radQuality!=0);
  505.  
  506.     // Set the Preview Start popup
  507.     if ((thePrefs->previewStart <= 0) || (thePrefs->previewEnd <= 0))
  508.     {
  509.         thePrefs->previewStart = 0; // OFF
  510.         thePrefs->previewEnd   = 0;
  511.     }
  512.     SetDialogItemValue(myDialog, kPU_PreviewStart, thePrefs->previewStart+1);
  513.  
  514.     // Set the Preview End popup
  515.     if (thePrefs->previewEnd > thePrefs->previewStart)
  516.         thePrefs->previewEnd = thePrefs->previewStart;
  517.     SetDialogItemValue(myDialog, kPU_PreviewEnd, thePrefs->previewEnd+1);
  518.  
  519.     // Set the Anti alias checkbox
  520.     SetDialogItemValue(myDialog, kCB_DoAntiAlias, thePrefs->doAntialias);
  521.  
  522.     SetDialogItemValue(myDialog, kPU_AntialiasMethod, thePrefs->antialiasMethod);
  523.  
  524.     sprintf(buff, "%.2f", thePrefs->antialiasThreshold);
  525.     c2pstr(buff);
  526.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntiAliasThresh), (StringPtr)buff );
  527.  
  528.     sprintf(buff, "%d", thePrefs->antialiasDepth);
  529.     c2pstr(buff);
  530.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntialiasDepth), (StringPtr)buff );
  531.  
  532.     sprintf(buff, "%.2f", thePrefs->antiJitterScale);
  533.     c2pstr(buff);
  534.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntiJitterScale), (StringPtr)buff );
  535.  
  536.     // Enable/disable the related fields, depending on AA setting
  537.     /* this is gross, so don't do it... [esp]
  538.     ShowHideDItem(myDialog, kPU_AntialiasMethod, thePrefs->doAntialias);
  539.     ShowHideDItem(myDialog, kET_AntiAliasThresh, thePrefs->doAntialias);
  540.     ShowHideDItem(myDialog, kET_AntialiasDepth,  thePrefs->doAntialias);
  541.     ShowHideDItem(myDialog, kET_AntiJitterScale, thePrefs->doAntialias);
  542.     */
  543.     } // SetupDitls_RPQuality
  544.  
  545.  
  546. static void ItemHit_RPQuality(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  547.     {
  548.     int            itChanged=0;
  549.     char        buff[128];
  550.  
  551.     thePrefs->renderQuality = GetDialogItemValue(myDialog, kPU_RenderQuality)-1;
  552.  
  553.     // See if radiosity flag is on or off
  554.     if (itemHit == kCB_RadQuality)
  555.         SetDialogItemValue(myDialog, kCB_RadQuality, !GetDialogItemValue(myDialog, kCB_RadQuality));
  556.     thePrefs->radQuality = GetDialogItemValue(myDialog, kCB_RadQuality);
  557.  
  558.     // If render quality is less than 8, then Radiosity MUST BE OFF
  559.     if (thePrefs->renderQuality < 8)
  560.         {
  561.         thePrefs->radQuality = 0;
  562.         // redraw it, in case it changed
  563.         SetDialogItemValue(myDialog, kCB_RadQuality, thePrefs->radQuality!=0);
  564.         }
  565.  
  566.     thePrefs->previewStart = GetDialogItemValue(myDialog, kPU_PreviewStart)-1;
  567.     if (thePrefs->previewStart < thePrefs->previewEnd)
  568.         {
  569.         itChanged++;
  570.         thePrefs->previewEnd = thePrefs->previewStart;
  571.         }
  572.     if (thePrefs->previewStart==0)
  573.         {
  574.         itChanged++;
  575.         thePrefs->previewEnd = 0; // Both OFF
  576.         }
  577.     if ((thePrefs->previewStart > 0) && (thePrefs->previewEnd == 0))
  578.         {
  579.         itChanged++;
  580.         thePrefs->previewEnd = 2; // Start is on, so turn End on too, to two x two :-)
  581.         }
  582.     // if either preview item changed, redisplay both at their new settings
  583.     if (itChanged)
  584.         {
  585.         SetDialogItemValue(myDialog, kPU_PreviewStart, thePrefs->previewStart+1);
  586.         SetDialogItemValue(myDialog, kPU_PreviewEnd,   thePrefs->previewEnd+1);
  587.         }
  588.  
  589.     thePrefs->previewEnd   = GetDialogItemValue(myDialog, kPU_PreviewEnd)-1;
  590.     if (thePrefs->previewEnd > thePrefs->previewStart)
  591.         { // bump start up to match
  592.         itChanged++;
  593.         thePrefs->previewStart = thePrefs->previewEnd;
  594.         }
  595.     if (thePrefs->previewEnd==0)
  596.         {
  597.         itChanged++;
  598.         thePrefs->previewStart = 0; // Both OFF
  599.         }
  600.     // if either preview item changed, re-display both at their new settings
  601.     if (itChanged)
  602.         {
  603.         SetDialogItemValue(myDialog, kPU_PreviewStart, thePrefs->previewStart+1);
  604.         SetDialogItemValue(myDialog, kPU_PreviewEnd,   thePrefs->previewEnd+1);
  605.         }
  606.  
  607.     if (itemHit == kCB_DoAntiAlias)
  608.         SetDialogItemValue(myDialog, kCB_DoAntiAlias, !GetDialogItemValue(myDialog, kCB_DoAntiAlias));
  609.     thePrefs->doAntialias = GetDialogItemValue(myDialog, kCB_DoAntiAlias);
  610.  
  611.     thePrefs->antialiasMethod = GetDialogItemValue(myDialog, kPU_AntialiasMethod);
  612.  
  613.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntiAliasThresh), (StringPtr)buff);
  614.     p2cstr((StringPtr)buff);
  615.     thePrefs->antialiasThreshold = atof(buff);
  616.     if (thePrefs->antialiasThreshold > 2.0)
  617.         thePrefs->antialiasThreshold = 2.0;
  618.     else if (thePrefs->antialiasThreshold < 0.0)
  619.         thePrefs->antialiasThreshold = 0.0;
  620.  
  621.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntialiasDepth), (StringPtr)buff);
  622.     p2cstr((StringPtr)buff);
  623.     thePrefs->antialiasDepth = atoi(buff);
  624.     thePrefs->antialiasDepth = PinValue(thePrefs->antialiasDepth, 1, 9);
  625.  
  626.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_AntiJitterScale), (StringPtr)buff);
  627.     p2cstr((StringPtr)buff);
  628.     thePrefs->antiJitterScale = atof(buff);
  629.     if (thePrefs->antiJitterScale > 2.0)
  630.         thePrefs->antiJitterScale = 2.0;
  631.     else if (thePrefs->antiJitterScale < 0.0)
  632.         thePrefs->antiJitterScale = 0.0;
  633.  
  634.     // Enable/disable the related fields, depending on AA setting
  635.     /* this is gross... [esp]
  636.     ShowHideDItem(myDialog, kPU_AntialiasMethod, thePrefs->doAntialias);
  637.     ShowHideDItem(myDialog, kET_AntiAliasThresh, thePrefs->doAntialias);
  638.     ShowHideDItem(myDialog, kET_AntialiasDepth,  thePrefs->doAntialias);
  639.     ShowHideDItem(myDialog, kET_AntiJitterScale, thePrefs->doAntialias);
  640.     */
  641.     } // ItemHit_RPQuality
  642.  
  643.             
  644.  
  645. // ---------------------------------------------------------------------
  646. static void SetupDitls_RPOptimiz(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  647.     {
  648.     // Set the Max Bounds popup
  649.     SetDialogItemValue(myDialog, kPU_MaxBounds,
  650.         thePrefs->doBoundSlabs ? 3 + (thePrefs->boundSlabThreshold / 5) : 1);
  651.  
  652.     SetDialogItemValue(myDialog, kCB_UseLBuffer,    thePrefs->doLightBuffer);
  653.     SetDialogItemValue(myDialog, kCB_UseVBuffer,    thePrefs->doVistaBuffer);
  654.     SetDialogItemValue(myDialog, kCB_UseVDraw,    thePrefs->doVistaDraw);
  655.  
  656.     SetDialogItemValue(myDialog, kCB_SplitUnions,    thePrefs->doSplitUnions);
  657.     SetDialogItemValue(myDialog, kCB_RemoveUnused,    thePrefs->removeBounds);
  658.     } // SetupDitls_RPOptimiz
  659.  
  660.  
  661. static void ItemHit_RPOptimiz(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  662.     {
  663.     // if popup is not at position 1 (off) then it must be on! :-)
  664.     thePrefs->doBoundSlabs = (GetDialogItemValue(myDialog, kPU_MaxBounds) > 1);
  665.     // off, ---, 1, 5, 10, 15, ...
  666.     thePrefs->boundSlabThreshold = (GetDialogItemValue(myDialog, kPU_MaxBounds)-3)*5;
  667.     // if popup was at position 1,2, set to 0...
  668.     if (thePrefs->boundSlabThreshold < 0)
  669.         thePrefs->boundSlabThreshold = 0;
  670.     else // if at 3, set the value to 1
  671.     if (thePrefs->boundSlabThreshold == 0)
  672.         thePrefs->boundSlabThreshold = 1;
  673.  
  674.     if (itemHit == kCB_UseLBuffer)
  675.         SetDialogItemValue(myDialog, kCB_UseLBuffer, !GetDialogItemValue(myDialog, kCB_UseLBuffer));
  676.     thePrefs->doLightBuffer = GetDialogItemValue(myDialog, kCB_UseLBuffer);
  677.  
  678.     if (itemHit == kCB_UseVBuffer)
  679.         SetDialogItemValue(myDialog, kCB_UseVBuffer, !GetDialogItemValue(myDialog, kCB_UseVBuffer));
  680.     thePrefs->doVistaBuffer = GetDialogItemValue(myDialog, kCB_UseVBuffer);
  681.  
  682.     if (itemHit == kCB_UseVDraw)
  683.         SetDialogItemValue(myDialog, kCB_UseVDraw, !GetDialogItemValue(myDialog, kCB_UseVDraw));
  684.     thePrefs->doVistaDraw = GetDialogItemValue(myDialog, kCB_UseVDraw);
  685.  
  686.     if (itemHit == kCB_SplitUnions)
  687.         SetDialogItemValue(myDialog, kCB_SplitUnions, !GetDialogItemValue(myDialog, kCB_SplitUnions));
  688.     thePrefs->doSplitUnions = GetDialogItemValue(myDialog, kCB_SplitUnions);
  689.  
  690.     if (itemHit == kCB_RemoveUnused)
  691.         SetDialogItemValue(myDialog, kCB_RemoveUnused, !GetDialogItemValue(myDialog, kCB_RemoveUnused));
  692.     thePrefs->removeBounds = GetDialogItemValue(myDialog, kCB_RemoveUnused);
  693.  
  694.     } // ItemHit_RPOptimiz
  695.  
  696.  
  697. // ---------------------------------------------------------------------
  698. static void SetupDitls_RPInfo(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  699.     {
  700.     // Set the Progress popup
  701.     if (thePrefs->progress < eProgNone)
  702.         thePrefs->progress = eProgNone;
  703.     else if (thePrefs->progress > eProgMax)
  704.         thePrefs->progress = eProgMax;
  705.     SetDialogItemValue(myDialog, kPU_Progress, thePrefs->progress+1);
  706.     // Set the Create INI checkbox
  707.     SetDialogItemValue(myDialog, kCB_DoCreateIni, thePrefs->doCreateINI);
  708.     } // SetupDitls_RPInfo
  709.  
  710.  
  711. static void ItemHit_RPInfo(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  712.     {
  713.     thePrefs->progress = GetDialogItemValue(myDialog, kPU_Progress)-1;
  714.     if (itemHit == kCB_DoCreateIni)
  715.         SetDialogItemValue(myDialog, itemHit, !GetDialogItemValue(myDialog, itemHit));
  716.     thePrefs->doCreateINI = GetDialogItemValue(myDialog, kCB_DoCreateIni);
  717.     } // ItemHit_RPInfo
  718.  
  719.  
  720. // ---------------------------------------------------------------------
  721. static void SetupDitls_RPOutputSize(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  722.     {
  723.     char    buff[128];
  724.  
  725.     // Set the Image Size Presets popup
  726.     SetDialogItemValue(myDialog, kPU_ImageSize,
  727.         GetClosestImageSizeItem(myDialog, thePrefs->imageWidth, thePrefs->imageHeight));
  728.  
  729.     sprintf(buff, "%d", thePrefs->imageWidth);
  730.     c2pstr(buff);
  731.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageWidth), (StringPtr)buff );
  732.  
  733.     sprintf(buff, "%d", thePrefs->imageHeight);
  734.     c2pstr(buff);
  735.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageHeight), (StringPtr)buff );
  736.  
  737.     sprintf(buff, "%d", thePrefs->selectionArea.top);
  738.     c2pstr(buff);
  739.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowFrom), (StringPtr)buff );
  740.  
  741.     sprintf(buff, "%d", thePrefs->selectionArea.bottom);
  742.     c2pstr(buff);
  743.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowTo), (StringPtr)buff );
  744.  
  745.     sprintf(buff, "%d", thePrefs->selectionArea.left);
  746.     c2pstr(buff);
  747.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColFrom), (StringPtr)buff );
  748.  
  749.     sprintf(buff, "%d", thePrefs->selectionArea.right);
  750.     c2pstr(buff);
  751.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColTo), (StringPtr)buff );
  752.  
  753.     } // SetupDitls_RPOutputSize
  754.  
  755.  
  756. static void UpdatePrefsWithImageSize(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  757.     {
  758.     char        buff[128];
  759.  
  760.     // width
  761.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageWidth), (StringPtr)buff);
  762.     p2cstr((StringPtr)buff);
  763.     thePrefs->imageWidth = atoi(buff);
  764.     thePrefs->imageWidth = PinValue(thePrefs->imageWidth, 1, 30000);
  765.  
  766.     // height
  767.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageHeight), (StringPtr)buff);
  768.     p2cstr((StringPtr)buff);
  769.     thePrefs->imageHeight = atoi(buff);
  770.     thePrefs->imageHeight = PinValue(thePrefs->imageHeight, 1, 30000);
  771.  
  772.     // from top
  773.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowFrom), (StringPtr)buff);
  774.     p2cstr((StringPtr)buff);
  775.     thePrefs->selectionArea.top = atoi(buff);
  776.     thePrefs->selectionArea.top = PinValue(thePrefs->selectionArea.top, 1, thePrefs->imageHeight);
  777.  
  778.     // to bottom
  779.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowTo), (StringPtr)buff);
  780.     p2cstr((StringPtr)buff);
  781.     thePrefs->selectionArea.bottom = atoi(buff);
  782.     thePrefs->selectionArea.bottom = PinValue(thePrefs->selectionArea.bottom, 1, thePrefs->imageHeight);
  783.  
  784.     // from left
  785.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColFrom), (StringPtr)buff);
  786.     p2cstr((StringPtr)buff);
  787.     thePrefs->selectionArea.left = atoi(buff);
  788.     thePrefs->selectionArea.left = PinValue(thePrefs->selectionArea.left,
  789.                                         1, thePrefs->imageWidth);
  790.  
  791.     // to right
  792.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColTo), (StringPtr)buff);
  793.     p2cstr((StringPtr)buff);
  794.     thePrefs->selectionArea.right = atoi(buff);
  795.     thePrefs->selectionArea.right = PinValue(thePrefs->selectionArea.right,
  796.                                         1, thePrefs->imageWidth);
  797.  
  798.     } // UpdatePrefsWithImageSize
  799.  
  800.  
  801. static void ItemHit_RPOutputSize(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  802.     {
  803.     short        index;
  804.     short        itemWidth=0, itemHeight=0;
  805.     MenuRef        imageMenuRef;
  806.     char        buff[128];
  807.  
  808.     // if popup hit, fill in related fields
  809.     if (itemHit == kPU_ImageSize)
  810.         {
  811.         ControlHandle    popupControlH;
  812.  
  813.         // get the popup menu control, then get menu handle from it
  814.         popupControlH = (ControlHandle)GrabDItemHandle(myDialog,kPU_ImageSize);
  815.         // popup menu handle inside struct pointed to by contrlData handle! (NIM:Essentials:5-28,5-77)
  816.         imageMenuRef = (MenuRef) (**(Handle**)(**popupControlH).contrlData);
  817.  
  818.         // get index of popup menu item chosen from image size popup
  819.         index = GetDialogItemValue(myDialog, itemHit);
  820.  
  821.         // Find w/h of the item chosen
  822.         GetImageSizeOfItem(imageMenuRef, index, &itemWidth, &itemHeight);
  823.  
  824.         // from top (always 1)
  825.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowFrom), (StringPtr)"\p1");
  826.         // from left (always 1)
  827.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColFrom), (StringPtr)"\p1");
  828.  
  829.         // width
  830.         sprintf(buff, "%d", itemWidth);    // X (width)
  831.         c2pstr(buff);
  832.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageWidth), (StringPtr)buff);
  833.         // to right
  834.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ColTo), (StringPtr)buff);
  835.  
  836.         // height
  837.         sprintf(buff, "%d", itemHeight); // Y (height)
  838.         c2pstr(buff);
  839.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ImageHeight), (StringPtr)buff);
  840.         // to bottom
  841.         SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_RowTo), (StringPtr)buff);
  842.  
  843.         // re-select first item (its size may have changed)
  844.         SelectDialogItemText(myDialog, kET_ImageWidth, 0, -1);
  845.         }
  846.  
  847.     // refill prefs record with new image size values
  848.     UpdatePrefsWithImageSize(myDialog, thePrefs);
  849.  
  850.     // update/repaint text fields in dialog?
  851.     // NOTE the "gPrevItemHit != kNoItemHit" check keeps us from updating the partial fields on first typing.
  852.     if (((itemHit != gPrevItemHit) && (gPrevItemHit != kNoItemHit))
  853.     || (itemHit == kPU_ImageSize))
  854.         SetupDitls_RPOutputSize(myDialog, thePrefs);
  855.  
  856.     } // ItemHit_RPOutputSize
  857.  
  858.  
  859.  
  860. // ---------------------------------------------------------------------
  861. static void SetupDitls_RPOutputFile(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  862.     {
  863.     short        menuValue;
  864.     char        buff4[6];
  865.     Str255        menuItemString;
  866.  
  867.     // Set PICT signature (make into a Pascal string)
  868.     buff4[0] = 4; // length byte
  869.     BlockMove(&thePrefs->pictFileCreator, &buff4[1], 4);
  870.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_PICTSig), (StringPtr)buff4);
  871.  
  872.     // Set Targa signature (make into a Pascal string)
  873.     buff4[0] = 4; // length byte
  874.     BlockMove(&thePrefs->targaFileCreator, &buff4[1], 4);
  875.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_TargaSig), (StringPtr)buff4);
  876.  
  877.     // Set the output file type (pict, pict+targa, etc.)
  878.     thePrefs->outfileType = PinValue(thePrefs->outfileType, eOutfNone, eOutfMax);
  879.     SetDialogItemValue(myDialog, kPU_OutfileType, thePrefs->outfileType+1);
  880.  
  881.     // enable the control only if they have chosen some non-PICT output file
  882.     // Technically the user could resume a render in PICT-only mode, however,
  883.     // I got many bug reports of people trying to ALWAYS turn on resume, that I
  884.     // went back to the 2.2 UI way, and only allow resuming if they are creating a file.
  885.     SetDialogItemValue(myDialog, kCB_ContinueFromTarga,    thePrefs->continueTarga&&(thePrefs->outfileType>0));
  886.     HiliteControl(GrabDItemHandle(myDialog, kCB_ContinueFromTarga),
  887.             (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  888.  
  889.     // Set the output file buffer size
  890.     if (thePrefs->outfileBuffSize < 0)
  891.          thePrefs->outfileBuffSize = 0;
  892.     else if (thePrefs->outfileBuffSize > kMaxOutfileBuffSize)
  893.         thePrefs->outfileBuffSize = kMaxOutfileBuffSize;
  894.     // set it to 1, 2, 3, etc.
  895.     SetDialogItemValue(myDialog, kPU_OutfileBuffSize, thePrefs->outfileBuffSize+1);
  896.  
  897.     // set Histogram stuff.
  898.     SetDialogItemValue(myDialog, kCB_DoHistFile, thePrefs->doHistogram);
  899.     SetDialogItemValue(myDialog, kPU_HistFileType, thePrefs->histogramType);
  900.     HiliteControl(GrabDItemHandle(myDialog, kCB_DoHistFile), kControlInactivePart);        // disable for now..
  901.     HiliteControl(GrabDItemHandle(myDialog, kPU_HistFileType), kControlInactivePart);    // disable for now..
  902.  
  903.     // set bits/color
  904.     if (thePrefs->bitsPerColor < kMinBitsPerColor)
  905.          thePrefs->bitsPerColor = kMinBitsPerColor; // PNG minimum limitation
  906.     else if (thePrefs->bitsPerColor > kMaxBitsPerColor)
  907.         thePrefs->bitsPerColor = kMaxBitsPerColor;
  908.     // brute force, find menu index for number
  909.     {
  910.         short        menuItem;
  911.         ControlHandle    mcontrol;
  912.         MenuRef        bitsPerColorMenu;
  913.         mcontrol = GrabDItemHandle(myDialog, kPU_BitsPerColor);
  914.         // popup menu handle inside struct pointed to by contrlData handle! (NIM:Essentials:5-28,5-77)
  915.         bitsPerColorMenu = (MenuRef) (**(Handle**)(**mcontrol).contrlData);
  916.         // how many items on menu?
  917.         menuItem = CountMenuItems(bitsPerColorMenu);
  918.         // are we there yet? loop down through items looking for a match
  919.         do    {
  920.             // get the menu item text
  921.             GetMenuItemText(bitsPerColorMenu, menuItem, menuItemString);
  922.             // convert it to a number (just the first part)
  923. //            StringToNum((StringPtr)menuItemString, &menuValue);
  924.             menuValue = atoi((char*)&menuItemString[1]);
  925.             // if it matches, we found it, drop out
  926.             if (menuValue == thePrefs->bitsPerColor)
  927.                 break;
  928.             // nope, keep looking
  929.             menuItem--;
  930.             } while (menuItem>1);
  931.         // set menu to the menu item found
  932.         SetDialogItemValue(myDialog, kPU_BitsPerColor, menuItem);
  933.     }
  934.     // disable this item if no special output file is used
  935.     // (PICTs are always 24-bit in 3.0)
  936.     HiliteControl(GrabDItemHandle(myDialog, kPU_BitsPerColor),
  937.             (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  938.  
  939.     // set alpha channel stuff.
  940.     SetDialogItemValue(myDialog, kCB_DoAlphaChannel, thePrefs->doAlphaChannel);
  941.     // disable this item if no special output file is used
  942. // (nope, allow turning PICT alpha channel on and off! 3.0.1 late beta [esp])
  943. //    HiliteControl(GrabDItemHandle(myDialog, kCB_DoAlphaChannel),
  944. //            (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  945.  
  946.     } // SetupDitls_RPOutputFile
  947.  
  948.  
  949. // ---------------------------------------------------------------------
  950. static void ItemHit_RPOutputFile(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  951.     {
  952.     short        menuValue;
  953.     char        buff[128];
  954.     Str255        menuItemString;
  955.  
  956.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_PICTSig), (StringPtr)buff);
  957.     p2cstr((StringPtr)buff);
  958.     thePrefs->pictFileCreator = *(OSType*)buff; // grab 1st 4 bytes as if they were a long int
  959.  
  960.     GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_TargaSig), (StringPtr)buff);
  961.     p2cstr((StringPtr)buff);
  962.     thePrefs->targaFileCreator = *(OSType*)buff; // grab 1st 4 bytes as if they were a long int
  963.  
  964.     thePrefs->outfileType = GetDialogItemValue(myDialog, kPU_OutfileType)-1;
  965.  
  966.     if (itemHit == kCB_ContinueFromTarga)
  967.         SetDialogItemValue(myDialog, kCB_ContinueFromTarga, !GetDialogItemValue(myDialog, kCB_ContinueFromTarga));
  968.     // enable the control only if they have chosen some non-PICT output file
  969.     // Technically the user could resume a render in PICT-only mode, however,
  970.     // I got many bug reports of people trying to ALWAYS turn on resume, that I
  971.     // went back to the 2.2 UI way, and only allow resuming if they are creating a Targa/PNG file.
  972.     if (thePrefs->outfileType==eOutfNone)
  973.         SetDialogItemValue(myDialog, kCB_ContinueFromTarga, 0);
  974.     thePrefs->continueTarga = GetDialogItemValue(myDialog, kCB_ContinueFromTarga);
  975.     HiliteControl(GrabDItemHandle(myDialog, kCB_ContinueFromTarga),
  976.             (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  977.  
  978.     thePrefs->outfileBuffSize = GetDialogItemValue(myDialog, kPU_OutfileBuffSize)-1;
  979.  
  980.     // histogram
  981.     if (itemHit == kCB_DoHistFile)
  982.         SetDialogItemValue(myDialog, itemHit, !GetDialogItemValue(myDialog, itemHit));
  983.     thePrefs->doHistogram = GetDialogItemValue(myDialog, kCB_DoHistFile);
  984.     thePrefs->histogramType = GetDialogItemValue(myDialog, kPU_HistFileType);
  985.  
  986.     // set bits/color to N from menu
  987.     {
  988.         short            menuItem;
  989.         ControlHandle    mcontrol;
  990.         MenuRef        bitsPerColorMenu;
  991.         menuItem = GetDialogItemValue(myDialog, kPU_BitsPerColor);
  992.         mcontrol = GrabDItemHandle(myDialog, kPU_BitsPerColor);
  993.         // popup menu handle inside struct pointed to by contrlData handle! (NIM:Essentials:5-28,5-77)
  994.         bitsPerColorMenu = (MenuRef) (**(Handle**)(**mcontrol).contrlData);
  995.         GetMenuItemText(bitsPerColorMenu, menuItem, menuItemString);
  996.         // convert it to a number (just the first part)
  997. //        StringToNum((StringPtr)menuItemString, &menuValue);
  998.         menuValue = atoi((char*)&menuItemString[1]);
  999.         // set bits/color to that value
  1000.         thePrefs->bitsPerColor = menuValue;
  1001.     }
  1002.     // disable this item if no special output file is used
  1003.     // (PICTs are always 24-bit in 3.0)
  1004.     HiliteControl(GrabDItemHandle(myDialog, kPU_BitsPerColor),
  1005.             (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  1006.  
  1007.     // set alpha channel stuff.
  1008.     SetDialogItemValue(myDialog, kCB_DoAlphaChannel, thePrefs->doAlphaChannel);
  1009.     // if checkbox clicked, invert it
  1010.     if (itemHit == kCB_DoAlphaChannel)
  1011.         SetDialogItemValue(myDialog, itemHit, !GetDialogItemValue(myDialog, itemHit));
  1012.     // get it's current setting
  1013.     thePrefs->doAlphaChannel = GetDialogItemValue(myDialog, kCB_DoAlphaChannel);
  1014. /*
  1015.     // disable this item if no special output file is used
  1016.     HiliteControl(GrabDItemHandle(myDialog, kCB_DoAlphaChannel),
  1017.             (thePrefs->outfileType>eOutfNone)?kControlNoPart:kControlInactivePart);
  1018. */
  1019.  
  1020. /*
  1021.     // pict compression button
  1022.     thePrefs->doCompression = GetDialogItemValue(myDialog, kCB_DoPICTCmp);
  1023.     if (thePrefs->doCompression)
  1024.         (void)SCGetInfo(gtheSCComponent, scSpatialSettingsType, &(**gDefltFilePrefs_h).sc_DialogParams);
  1025. */
  1026.     } // ItemHit_RPOutputFile
  1027.  
  1028.  
  1029. // ---------------------------------------------------------------------
  1030. static void SetupDitls_RPAnimate(DialogPtr myDialog, file_prefs_ptr_t thePrefs)
  1031.     {
  1032.     float    fval;
  1033.     char    buff[128];
  1034.  
  1035.     SetDialogItemValue(myDialog, kCB_Animate, thePrefs->doAnimation!=0);
  1036.  
  1037.     // Initial Frame
  1038.     sprintf(buff, "%d", thePrefs->animRec.frameVal0); // always starts at frame 1
  1039.     c2pstr(buff);
  1040.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kST_FrameVal0), (StringPtr)buff);
  1041.  
  1042.     // Start Frame
  1043.     sprintf(buff, "%d", thePrefs->animRec.frameValS);
  1044.     c2pstr(buff);
  1045.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValS), (StringPtr)buff);
  1046.  
  1047.     // End Frame
  1048.     sprintf(buff, "%d", thePrefs->animRec.frameValE);
  1049.     c2pstr(buff);
  1050.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValE), (StringPtr)buff);
  1051.  
  1052.     // Final Frame
  1053.     sprintf(buff, "%d", thePrefs->animRec.frameValN);
  1054.     c2pstr(buff);
  1055.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValN), (StringPtr)buff);
  1056.  
  1057.     // Initial Clock
  1058.     sprintf(buff, "%g", thePrefs->animRec.clockVal0);
  1059.     c2pstr(buff);
  1060.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ClockVal0), (StringPtr)buff);
  1061.  
  1062.     // Start Clock
  1063.     fval = CalcClockVal(&thePrefs->animRec, thePrefs->animRec.frameValS);
  1064.     sprintf(buff, "%g", fval);
  1065.     c2pstr(buff);
  1066.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kST_ClockValS), (StringPtr)buff);
  1067.  
  1068.     // End Clock
  1069.     fval = CalcClockVal(&thePrefs->animRec, thePrefs->animRec.frameValE);
  1070.     sprintf(buff, "%g", fval);
  1071.     c2pstr(buff);
  1072.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kST_ClockValE), (StringPtr)buff);
  1073.  
  1074.     // Final Clock
  1075.     sprintf(buff, "%g", thePrefs->animRec.clockValN);
  1076.     c2pstr(buff);
  1077.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ClockValN), (StringPtr)buff);
  1078.  
  1079.     // Field rendering popup
  1080.     if (!thePrefs->doFieldRender)
  1081.         SetDialogItemValue(myDialog, kPU_FieldRender, 1); // 1=OFF
  1082.     else
  1083.         SetDialogItemValue(myDialog, kPU_FieldRender, 2+thePrefs->doOddField); // 2=Even, 3=Odd
  1084.  
  1085.     } // SetupDitls_RPAnimate
  1086.  
  1087.  
  1088. static void ItemHit_RPAnimate(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs)
  1089.     {
  1090.     char    buff[32];
  1091.  
  1092.     if (itemHit == kCB_Animate)
  1093.         {
  1094.             SetDialogItemValue(myDialog, itemHit, !GetDialogItemValue(myDialog, itemHit));
  1095.             thePrefs->doAnimation = GetDialogItemValue(myDialog, itemHit);
  1096.         }
  1097.     else
  1098.         {
  1099.         //
  1100.         // Initial Frame = 1 always
  1101.         thePrefs->animRec.frameVal0 = 1;
  1102.  
  1103.         //
  1104.         // Final Frame
  1105.         GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValN), (StringPtr)buff);
  1106.         p2cstr((StringPtr)buff);
  1107.         if (buff[0] == 0) // null string
  1108.             thePrefs->animRec.frameValN = thePrefs->animRec.frameVal0;
  1109.         else
  1110.             thePrefs->animRec.frameValN = atoi(buff);
  1111.         // Final must be greater than or equal to Initial
  1112.         if (thePrefs->animRec.frameValN < thePrefs->animRec.frameVal0)
  1113.             thePrefs->animRec.frameValN = thePrefs->animRec.frameVal0;
  1114.  
  1115.         //
  1116.         // Start Frame
  1117.         GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValS), (StringPtr)buff);
  1118.         p2cstr((StringPtr)buff);
  1119.         if (buff[0] == 0) // null string
  1120.             thePrefs->animRec.frameValS = thePrefs->animRec.frameVal0;
  1121.         else
  1122.             thePrefs->animRec.frameValS = atoi(buff);
  1123.         if ((thePrefs->animRec.frameValS < thePrefs->animRec.frameVal0)
  1124.         || (thePrefs->animRec.frameValS > thePrefs->animRec.frameValN))
  1125.             thePrefs->animRec.frameValS = thePrefs->animRec.frameVal0;
  1126.  
  1127.         //
  1128.         // End Frame
  1129.         GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_FrameValE), (StringPtr)buff);
  1130.         p2cstr((StringPtr)buff);
  1131.         if (buff[0] == 0) // null string
  1132.             thePrefs->animRec.frameValE = thePrefs->animRec.frameValN;
  1133.         else
  1134.             thePrefs->animRec.frameValE = atoi(buff);
  1135.         // End must be greater than start...
  1136.         if (thePrefs->animRec.frameValE < thePrefs->animRec.frameVal0)
  1137.             thePrefs->animRec.frameValE = thePrefs->animRec.frameValN;
  1138.         // If End is greater than Final, bump final up
  1139.         if (thePrefs->animRec.frameValE > thePrefs->animRec.frameValN)
  1140.             thePrefs->animRec.frameValN = thePrefs->animRec.frameValE;
  1141.  
  1142.         //
  1143.         // Do Start & End Frame overlap?
  1144.         if (thePrefs->animRec.frameValE < thePrefs->animRec.frameValS)
  1145.             thePrefs->animRec.frameValE = thePrefs->animRec.frameValS;
  1146.  
  1147.         //
  1148.         // Initial Clock Val
  1149.         GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ClockVal0), (StringPtr)buff);
  1150.         p2cstr((StringPtr)buff);
  1151.         if (buff[0] == 0) // null string
  1152.             thePrefs->animRec.clockVal0 = 0.0;
  1153.         else
  1154.             thePrefs->animRec.clockVal0 = atof(buff);
  1155.  
  1156.         //
  1157.         // Final Clock Val
  1158.         GetDialogItemText((Handle)GrabDItemHandle(myDialog,kET_ClockValN), (StringPtr)buff);
  1159.         p2cstr((StringPtr)buff);
  1160.         if (buff[0] == 0) // null string
  1161.             thePrefs->animRec.clockValN = 1.0;
  1162.         else
  1163.             thePrefs->animRec.clockValN = atof(buff);
  1164.  
  1165.         //
  1166.         // Final & Initial clock are too close, change Final
  1167.         if (fabs(thePrefs->animRec.clockValN-thePrefs->animRec.clockVal0) < 1.0e-9)
  1168.             {
  1169.             thePrefs->animRec.clockValN = thePrefs->animRec.clockVal0 + 1.0;
  1170.             SysBeep(4);
  1171.             }
  1172.  
  1173.         //
  1174.         // Field Rendering setting ( 1=off, 2=even, 3=odd)
  1175.         thePrefs->doFieldRender = GetDialogItemValue(myDialog, kPU_FieldRender) > 1; // >1 means it is ON
  1176.         thePrefs->doOddField = GetDialogItemValue(myDialog, kPU_FieldRender) == 3; // 3 = Odd field
  1177.     
  1178.         }
  1179.  
  1180.     // Force a redraw of everything since we've updated fields
  1181.     if (itemHit != gPrevItemHit)
  1182.         SetupDitls_RPAnimate(myDialog, thePrefs);
  1183.  
  1184.     }
  1185.  
  1186.  
  1187. // ---------------------------------------------------------------------
  1188. static void DoInitDitl(DialogPtr myDialog, file_prefs_ptr_t thePrefs, short currDITLID)
  1189. {
  1190.     switch (currDITLID)
  1191.         {
  1192.         case KDITL_RPInput:
  1193.             SetupDitls_RPInput(myDialog, thePrefs);
  1194.             break;
  1195.         case KDITL_RPQuality:
  1196.             SetupDitls_RPQuality(myDialog, thePrefs);
  1197.             break;
  1198.         case KDITL_RPOptimiz:
  1199.             SetupDitls_RPOptimiz(myDialog, thePrefs);
  1200.             break;
  1201.         case KDITL_RPInfo:
  1202.             SetupDitls_RPInfo(myDialog, thePrefs);
  1203.             break;
  1204.         case KDITL_RPOutputSize:
  1205.             SetupDitls_RPOutputSize(myDialog, thePrefs);
  1206.             break;
  1207.         case KDITL_RPOutputFile:
  1208.             SetupDitls_RPOutputFile(myDialog, thePrefs);
  1209.             break;
  1210.         case KDITL_RPAnimate:
  1211.             SetupDitls_RPAnimate(myDialog, thePrefs);
  1212.             break;
  1213.         }
  1214. } // DoInitDitl
  1215.  
  1216.  
  1217. // ---------------------------------------------------------------------
  1218. static void DoItemHit(DialogPtr myDialog, short itemHit, file_prefs_ptr_t thePrefs, short currDITLID)
  1219. {
  1220.     switch (currDITLID)
  1221.         {
  1222.         case KDITL_RPInput:
  1223.             ItemHit_RPInput(myDialog, itemHit, thePrefs);
  1224.             break;
  1225.         case KDITL_RPQuality:
  1226.             ItemHit_RPQuality(myDialog, itemHit, thePrefs);
  1227.             break;
  1228.         case KDITL_RPOptimiz:
  1229.             ItemHit_RPOptimiz(myDialog, itemHit, thePrefs);
  1230.             break;
  1231.         case KDITL_RPInfo:
  1232.             ItemHit_RPInfo(myDialog, itemHit, thePrefs);
  1233.             break;
  1234.         case KDITL_RPOutputSize:
  1235.             ItemHit_RPOutputSize(myDialog, itemHit, thePrefs);
  1236.             break;
  1237.         case KDITL_RPOutputFile:
  1238.             ItemHit_RPOutputFile(myDialog, itemHit, thePrefs);
  1239.             break;
  1240.         case KDITL_RPAnimate:
  1241.             ItemHit_RPAnimate(myDialog, itemHit, thePrefs);
  1242.             break;
  1243.         }
  1244. } // DoItemHit
  1245.  
  1246.  
  1247. // ---------------------------------------------------------------------
  1248. // Prompt the user to change the File Preferences, handle clicks in the dialog
  1249. static void FilePrefs_HandleEvents(EventRecord * theEventPtr)
  1250.     {
  1251.     short        itemHit;
  1252.     Boolean        gotItem;
  1253.     WindowPtr    myDialog;
  1254.     Rect        dRect;
  1255.  
  1256.     gotItem = false;
  1257.     myDialog = GetCurrMModalDialog();
  1258.  
  1259.     // handle activate events
  1260.     if (theEventPtr->what == activateEvt)
  1261.         {
  1262.         // enable or disable our main buttons on activate/deactivate
  1263.         HiliteControl(GrabDItemHandle(myDialog, ok), (theEventPtr->modifiers & 1)?kControlNoPart:kControlInactivePart);
  1264.         HiliteControl(GrabDItemHandle(myDialog, cancel), (theEventPtr->modifiers & 1)?kControlNoPart:kControlInactivePart);
  1265.         }
  1266.  
  1267.     // Handle CR/ESC ourselves
  1268.     if (theEventPtr->what == keyDown)
  1269.         {
  1270.         char    theKey = theEventPtr->message & charCodeMask;
  1271.         if ((theKey == 13) || (theKey == 3)) // CR or ENTER
  1272.             {
  1273.             itemHit = ok;
  1274.             gotItem = true;
  1275.             FlashDItem(myDialog, itemHit);
  1276.             }
  1277.         if ((theKey == 27) ||        // escape key
  1278.             ((theKey == '.') && (theEventPtr->modifiers & cmdKey))) // <cmd>-period
  1279.             {
  1280.             itemHit = cancel;
  1281.             gotItem = true;
  1282.             FlashDItem(myDialog, itemHit);
  1283.             }
  1284.         }
  1285.  
  1286.     // look for other events
  1287.     if (!gotItem)
  1288.         gotItem = DialogSelect(theEventPtr, &myDialog, &itemHit);
  1289.  
  1290.     if (gotItem)
  1291.         {
  1292.         switch (itemHit)
  1293.             {
  1294.             case ok:
  1295.                 // NOTE: We are already writing straight into prefs record,
  1296.                 // so we don't need to do anything on OK, just cancel.
  1297.  
  1298.                 // Remember where we parked
  1299.                 GetGlobalWindowRect(myDialog, &dRect); // ScreenUtils.c
  1300.                 APSet_FilePrefsDlgPos(&dRect);
  1301.  
  1302.                 // save prefs in file
  1303.                 FilePrefs_Write(gSrc_wdrefnum, gSrc_fname);
  1304.     
  1305.                 CloseMModalDialog();
  1306.                 EnableMenus(); // re-enable menus
  1307.                 break;
  1308.  
  1309.             case cancel:
  1310.                 **gFilePrefs_h = gOrigPrefs; // restore original values
  1311.                 CloseMModalDialog();
  1312.                 EnableMenus(); // re-enable menus
  1313.                 break;
  1314.  
  1315.             case kPU_Settings:
  1316.                 // only slide in another pane if we chose one other than the current pane
  1317.                 if (gCurrDITLID != kDLOG_RenderPrefsMain + GetDialogItemValue(myDialog, kPU_Settings))
  1318.                     {
  1319.                     // if switching old pane out, fake one last hit to grab current settings
  1320.                     // before tearing it down
  1321.                     DoItemHit(myDialog, kNoItemHit, *gFilePrefs_h, gCurrDITLID);
  1322.                     // now slide in new pane
  1323.                     SlideInNewDITL(myDialog);
  1324.                     // force a redraw
  1325.                     InvalRect(&myDialog->portRect); // full redraw, yuck
  1326.                     // reset prev item hit
  1327.                     gPrevItemHit = kNoItemHit;
  1328.                     // set up the sub-panel's control values
  1329.                     DoInitDitl(myDialog, *gFilePrefs_h, gCurrDITLID);
  1330.                     }
  1331.                 break;
  1332.  
  1333.             case kCB_SaveAsDefault:
  1334.                 // save these values as defaults
  1335.                 **gDefltFilePrefs_h = **gFilePrefs_h;
  1336.                 break;
  1337.  
  1338.             case kPB_RestoreDefault:
  1339.                 // push app default values into this file's settings
  1340.                 **gFilePrefs_h = **gDefltFilePrefs_h;
  1341.                 // reset/reread the sub-panel's control values
  1342.                 DoInitDitl(myDialog, *gFilePrefs_h, gCurrDITLID);
  1343.                 break;
  1344.  
  1345.             // otherwise, it is one of the specialized items, dispatch to appropriate handler
  1346.             default:
  1347.                 DoItemHit(myDialog, itemHit, *gFilePrefs_h, gCurrDITLID);
  1348.                 // remember item for next time through
  1349.                 gPrevItemHit = itemHit;
  1350.                 break;
  1351.             } // switch
  1352.         } // if
  1353.     } // FilePrefs_HandleEvents
  1354.  
  1355.  
  1356. // ---------------------------------------------------------------------
  1357. // Prompt the user to change the File Preferences, Start the dialog
  1358. void FilePrefs_Prompt_Init(short src_wdrefnum, StringPtr src_fname)
  1359.     {
  1360.     Rect            aRect;
  1361.     DialogPtr        myDialog;
  1362.  
  1363.     // retrieve dialog from resource
  1364.     myDialog = GetMModalDialog(kDLOG_RenderPrefsMain);
  1365.     if (!myDialog)
  1366.         {
  1367.         SysBeep(3);
  1368.         return;
  1369.         }
  1370.  
  1371.     // set this as current dialog and event handler
  1372.     SetCurrMModalDialog(myDialog, &FilePrefs_HandleEvents); // dialogutils
  1373.  
  1374.     // remember temporary prefs record until user clicks OK!
  1375.     gOrigPrefs        = **gFilePrefs_h;
  1376.     gSrc_wdrefnum    = src_wdrefnum;
  1377.     gSrc_fname        = src_fname;
  1378.     gPrevItemHit    = 0;
  1379.  
  1380.     // Set the Settings popup to wherever we are
  1381.     SetDialogItemValue(myDialog, kPU_Settings, gCurrDITLID-kDLOG_RenderPrefsMain);
  1382.  
  1383.     // Set dialog's File name display
  1384.     SetDialogItemText((Handle)GrabDItemHandle(myDialog,kST_Filename), src_fname);
  1385.  
  1386.     // set up appropriate dialog items in pane
  1387.     SlideInNewDITL(myDialog);
  1388.  
  1389.     // init other stuff here
  1390.     DoInitDitl(myDialog, *gFilePrefs_h, gCurrDITLID);
  1391.  
  1392.     // position our dialog where user last left it
  1393.     APGet_FilePrefsDlgPos(&aRect);
  1394.     if ((aRect.left==0) && (aRect.top==0))
  1395.         PositionWindow(myDialog, ewcDoCentering, eSameAsPassedWindow, (WindowPtr)gp2wWindow);
  1396.     else
  1397.         {
  1398.         // make sure our windows are visible on THIS MACHINE'S screens
  1399.         ForceRectOnScreen(&aRect);
  1400.         MoveWindow(myDialog, aRect.left, aRect.top, true);
  1401.         }
  1402.  
  1403.     // set the standard action for OK/cancel buttons
  1404.     InstallUserDrawProc(myDialog, kDefaultOutlineItem, &OutlineButtonDrawProc);
  1405.  
  1406.     // show it
  1407.     ShowMModalDialog();
  1408.  
  1409.     } // FilePrefs_Prompt_Init
  1410.  
  1411.  
  1412.